package com.cehome.cloudbox.base;
import com.cehome.cloudbox.utils.I18nUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

@ApiModel(value = "R", description = "框架统一返回体")
@Data
public class R<T> implements Serializable {
    @ApiModelProperty("业务执行状态(非http状态)")
    private Integer status;
    @ApiModelProperty("提示信息code")
    private String code;
    @ApiModelProperty("详细提示信息")
    private String message;
    @ApiModelProperty("泛型结果体")
    private T data;
    @JsonIgnore
    private Throwable e;

    public static <Z> R<Z> ok() {
        return new R(0);
    }

    public static <Z> R<Z> data(Z data) {
        return new R(0, data);
    }

    public static <Z> R<Z> data(Z data, String code, String... args) {
        return new R(0, data, code, args);
    }

    public static <Z> R<Z> code(String code, String... args) {
        return new R(0, code, new Object[]{code, args});
    }

    public static <Z> R<Z> message(Integer status, String msg) {
        return new R(true, status, msg);
    }

    public static <Z> R<Z> ng() {
        return new R(1);
    }

    public static <Z> R<Z> ng(String code) {
        return new R(1, code, new Object[0]);
    }

    public static <Z> R<Z> ng(String code, Object... args) {
        return new R(1, code, args);
    }

    public static <Z> R<Z> ng(Z data, String code, Object[] args) {
        return new R(1, data, code, args);
    }

    public static <Z> R<Z> exception(Throwable e) {
        return new R(1, e);
    }

    public static <Z> R<Z> exception(Integer status, Throwable e) {
        return new R(status, e);
    }

    public static <Z> R<Z> exception(String code, Object... args) {
        return new R(1, code, args);
    }

    public static <Z> R<Z> exception(Integer status, String code) {
        return new R(status, code, new Object[0]);
    }

    public static <Z> R<Z> exception(Integer status, String code, Object... args) {
        return new R(status, code, args);
    }

    public R() {
    }

    private R(Integer status) {
        this.status = status;
    }

    private R(boolean isMsg, Integer status, String msg) {
        this.status = status;
        this.message = msg;
    }

    private R(Integer status, T data) {
        this.status = status;
        this.data = data;
    }

    private R(Integer status, T data, String code) {
        this.status = status;
        this.data = data;
        this.code = code;
        this.message = I18nUtils.message(code, new Object[0]);
    }

    private R(Integer status, T data, String code, Object... args) {
        this.status = status;
        this.data = data;
        this.code = code;
        this.message = I18nUtils.message(code, args);
    }

    private R(Integer status, String code, Object... args) {
        this.status = status;
        this.code = code;
        this.message = I18nUtils.message(code, args);
    }

    private R(Integer status, Throwable e) {
        this.status = status;
        this.message = e.getLocalizedMessage();
        this.e = e;
    }

}
